package com.sxw.interceptor;

import com.alibaba.fastjson2.JSONObject;
import com.sxw.dto.PlayerSessionDto;
import com.sxw.utils.JwtTokenProvider;
import com.sxw.utils.RedisUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import java.util.List;
import java.util.Map;

@Component
@RequiredArgsConstructor
public class WebSocketAuthHandshakeInterceptor implements HandshakeInterceptor {

    private final JwtTokenProvider jwtUtil;
    private final RedisUtils redisUtils;

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        // 1. 从请求参数获取Token
        String token = getTokenFromRequest(request);
        // 2. 校验JWT签名是否有效、是否过期
        if (token == null || !jwtUtil.validateToken(token)) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return false;
        }
        // 3. 从JWT中解析出用户ID
        String username = jwtUtil.getUsernameFromToken(token);
        // 4. 基于用户ID，去Redis中查找Session，判断用户是否真的"在线"
        // 注意：现在我们使用登录名作为键，而不是用户ID
        String redisKey = "player:session:" + username;
        // 尝试不同类型的键来查找会话
        Object sessionObj = redisUtils.get(redisKey);
        PlayerSessionDto playerSession = null;
        if (sessionObj != null) {
            playerSession = JSONObject.parseObject(sessionObj.toString(), PlayerSessionDto.class);
        }
        if (playerSession == null) {
            // Redis中不存在，说明Session已过期，或已被强制下线
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return false;
        }
        // 5. 重要：更新Session活跃时间，防止过期
        playerSession.setLastActiveTime(System.currentTimeMillis());
        redisUtils.set(
            redisKey,
            JSONObject.toJSONString(playerSession),
            1800 // 重新设置30分钟过期
        );
        // 6. 将用户ID和Session信息存入WebSocket的Attributes，供后续业务使用
        attributes.put("userName", username);
        attributes.put("player_session", playerSession);
        return true; // 握手通过
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {

    }

    private String getTokenFromRequest(ServerHttpRequest request) {
        // ... 实现从Query参数或Header中获取Token的逻辑
        List<String> req = request.getHeaders().get("Authorization");
        if(null != req && !req.isEmpty()){
            return req.getFirst().substring(7);
        }
        return null;
    }
}